package org.geektimes.projects.user.web.controller;

import org.geektimes.projects.user.domain.User;
import org.geektimes.projects.user.service.UserService;
import org.geektimes.web.mvc.controller.PageController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.ElementKind;
import javax.validation.Validator;
import javax.validation.metadata.ConstraintDescriptor;
import javax.ws.rs.Path;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;

@Path("/register")
public class RegisterController implements PageController {

    private AtomicLong atomicLong = new AtomicLong(10);

    @Resource(name = "bean/DelegateValidation")
    private Validator validator;
    @Resource(name = "bean/UserService")
    private UserService userService;

    @Override
    @Path("/")
    public String execute(HttpServletRequest request, HttpServletResponse response) throws Throwable {
        String inputEmail = request.getParameter("inputEmail");
        String inputPassword = request.getParameter("inputPassword");
        String phone = request.getParameter("phone");
        User user  = new User();
        user.setId(atomicLong.incrementAndGet());
        user.setName("A");
        user.setEmail(inputEmail);
        user.setPassword(inputPassword);
        user.setPhoneNumber(phone);
        Set<ConstraintViolation<User>> violationSet = validator.validate(user);
        for (ConstraintViolation<User> violation : violationSet) {
            String filed = this.determineField(violation);
            ConstraintDescriptor<?> cd = violation.getConstraintDescriptor();
            String errorCode = this.determineError(cd);

            String message = violation.getMessage();
            request.setAttribute("message",filed + message);
            return "login-form.jsp";
        }
        userService.register(user);
        return "success.jsp";
    }

    private String determineError(ConstraintDescriptor<?> descriptor) {
        return descriptor.getAnnotation().annotationType().getSimpleName();
    }

    private String determineField(ConstraintViolation<User> violationSet) {
        javax.validation.Path path = violationSet.getPropertyPath();
        StringBuilder sb = new StringBuilder();
        boolean first = true;

        for (javax.validation.Path.Node node : path) {
            if (node.isInIterable()){
                sb.append('[');
                Object index = node.getIndex();
                if (null == index){
                    index = node.getKey();
                }
                if (index != null){
                    sb.append(index);
                }
                sb.append(']');
            }
            String name = node.getName();
            if (null != name && node.getKind() == ElementKind.PROPERTY && !name.startsWith("<")){
                if (!first){
                    sb.append('.');
                }
                first = false;
                sb.append(name);
            }
            return sb.toString();
        }

        return null;
    }
}
